home *** CD-ROM | disk | FTP | other *** search
- { EDIT.PAS
- Version 2.0
- Written by Bela Lubkin, 12/6/84
- Last revised 12/22/85
-
- This is a set of three routines that can be used in a Turbo Pascal program
- for getting input from the keyboard. Each routine provides WordStar-like
- single line editing of the input, an undo function, pre-setting of the input
- buffer and filtering for allowable characters and maximum string length.
-
- Function AskString(Prompt,Param: String255; LegalChars: CharSet;
- MaxLen: Byte): String255;
- -- prints the prompt string Prompt, then reads a string of length up to
- MaxLen, composed of characters in the set LegalChars. The string is
- initially filled with the contents of Param. If the global variable
- ShowBuffer is true, editing starts with the passed in value displayed,
- the cursor at the end; else it starts immediately following the prompt.
- The terminating character is returned in global variable AskTerminator.
- Other global parameters: AskNoisy, if true, sounds a bell if an attempt
- is made to insert a character beyond MaxLen. TermChars is a Set Of Char
- that lists all the allowable terminator characters. WordChars is a Set
- Of Char that lists which characters are considered part of a word.
-
- Function AskInt(Prompt: String255; Param: Integer; MaxLen: Byte): Integer;
- -- prints the prompt string Prompt, then reads a string of length up to
- MaxLen, composed of characters legal for an integer. The string is
- then converted to an integer and returned as the function result. The
- initial edit buffer is filled with the ASCII representation of Param.
- Everything else from AskString above applies.
-
- Function AskReal(Prompt: String255; Param: Real; MaxLen: Byte): Real;
- -- prints the prompt string Prompt, then reads a string of length up to
- MaxLen, composed of characters legal for a real. The string is then
- converted to a real and returned as the function result. The initial
- edit buffer is filled with the ASCII representation of Param.
- Everything else from AskString above applies.
-
- Here is a list of the control characters used (including synonymous IBM PC
- function keys):
-
- ^A Move back 1 word, nondestructive [Ctrl-LeftArrow]
- ^B Save current buffer in undo buffer
- ^C End of input; accept what is currently visible [Ctrl-Break]
- ^D Move forward one [RightArrow]
- ^F Move forward 1 word [Ctrl-RightArrow]
- ^G Delete character forward [DEL]
- ^H Move back 1, destructive (same as ASCII DEL) [BackSpace]
- ^J End of input; accept entire buffer [Ctrl-Enter]
- ^L Look for char: reads a character, advances cursor to match
- ^M End of input; accept what is currently visible [Enter]
- ^N End of input; accept entire buffer
- ^P Accept next character as-is (control character prefix)
- ^Q Move to beginning of line, nondestructive [Home]
- ^R Move to end of line [End]
- ^S Move back 1, nondestructive [LeftArrow]
- ^T Delete line forward [Ctrl-End]
- ^U Copy undo buffer into current buffer (undo)
- ^V Insert on/off [INS]
- ^X Move to beginning of line, destructive [Ctrl-Home]
- ^Y Delete line
- DEL Move back 1, destructive (same as ^H) (ASCII DEL) [Ctrl-BackSpace]
- ESC End of input; accept what is currently visible
-
- The initial contents of both the current buffer and the undo buffer are set
- by the parameter Param.
-
- These routines will work with any version of Turbo Pascal.
- }
-
- Type
- CharSet=Set Of Char;
- String255=String[255];
-
- Const
- TermChars: CharSet=[^C,^J,^M,^N,^[]; { Terminator characters }
- WordChars: CharSet=['0'..'9','A'..'Z','a'..'z']; { Legal chars in a 'word' }
- AskNoisy: Boolean=False; { Ring bell on insert with buffer full? }
- ShowBuffer: Boolean=False; { Display incoming input buffer at start? }
-
- Var
- AskTerminator: Char; { Output: the terminator used -- ^C, ^J, ^M, ^N, ESC }
-
- Function AskString(Prompt,Param: String255; LegalChars: CharSet;
- MaxLen: Byte): String255;
- Const
- ESC=^[;
- DEL=#$7F;
- InsertFlag: Boolean=True;
-
- Var
- AS: String255;
- Cursor: Integer;
- Ch,Ch2: Char;
- WasChar,First: Boolean;
-
- Function CanPut: Boolean;
- Begin
- CanPut:=(Length(AS)>Cursor) And (Cursor<MaxLen);
- End;
-
- Procedure PutC;
- Var
- C: Char;
- Begin
- Cursor:=Succ(Cursor);
- C:=AS[Cursor];
- If C<' ' Then Write('^',Chr(Ord(C)+64))
- Else Write(C);
- End; { PutC }
-
- Procedure UnPutC;
- Begin
- Write(^H' '^H);
- If AS[Cursor]<' ' Then Write(^H' '^H);
- Cursor:=Pred(Cursor);
- End; { UnPutC }
-
- Begin { AskString }
- Write(Prompt);
- AS:=Param;
- Cursor:=0;
- First:=True;
- Repeat
- If First And ShowBuffer Then
- Begin
- First:=False;
- Ch:=^R;
- End
- Else Read(Kbd,Ch);
- WasChar:=False;
- If (Ch=ESC) And KeyPressed Then
- Begin
- Read(Kbd,Ch);
- Case Ch Of
- 's': Ch:=^A; { Ctrl-LeftArrow }
- 'M': Ch:=^D; { RightArrow }
- 't': Ch:=^F; { Ctrl-RightArrow }
- 'S': Ch:=^G; { DEL }
- 'G': Ch:=^Q; { Home }
- 'O': Ch:=^R; { End }
- 'K': Ch:=^S; { LeftArrow }
- 'u': Ch:=^T; { Ctrl-End }
- 'R': Ch:=^V; { INS }
- 'w': Ch:=^X; { Ctrl-Home }
- Else Ch:='?';{ all unknowns }
- WasChar:=True;
- End;
- End;
- Case Ch Of
- ^Q,^U,^X,^Y: Begin
- While Cursor>0 Do
- Begin
- UnPutC;
- If Ch=^X Then Delete(AS,Succ(Cursor),1);
- End;
- If Ch=^U Then AS:=Param
- Else If Ch=^Y Then AS:='';
- End;
- ^A: Begin
- While (Cursor>0) And Not (AS[Cursor] In WordChars) Do UnPutC;
- If Cursor>0 Then UnPutC;
- While (Cursor>0) And (AS[Cursor] In WordChars) Do UnPutC;
- End;
- ^B: Param:=AS;
- ^D: If CanPut Then PutC;
- ^F: Begin
- If CanPut Then PutC;
- While CanPut And (AS[Succ(Cursor)] In WordChars) Do PutC;
- While CanPut And Not (AS[Succ(Cursor)] In WordChars) Do PutC;
- End;
- ^L: Begin
- Read(Kbd,Ch);
- If CanPut Then PutC;
- While CanPut And (AS[Succ(Cursor)]<>Ch) Do PutC;
- Ch:=^L;
- End;
- ^R,^N,^J: While CanPut Do PutC;
- ^G: Delete(AS,Succ(Cursor),1);
- ^H,^S,DEL: If Cursor>0 Then
- Begin
- UnPutC;
- If Ch<>^S Then Delete(AS,Succ(Cursor),1);
- End;
- ^P: Begin
- Read(Kbd,Ch);
- WasChar:=True;
- End;
- ^T: Delete(AS,Succ(Cursor),Length(AS));
- ^V: InsertFlag:=Not InsertFlag;
- { Case } Else WasChar:=Not (Ch In TermChars);
- End;
- If WasChar And (Cursor<MaxLen) And (Ch In LegalChars) Then
- Begin
- If InsertFlag Then Insert(Ch,AS,Succ(Cursor))
- Else AS[Succ(Cursor)]:=Ch;
- If Succ(Cursor)>Length(AS) Then AS[0]:=Chr(Succ(Cursor));
- PutC;
- End
- Else If AskNoisy And WasChar Then Write(^G); { Ring bell, if AskNoisy }
- Until (Ch In TermChars) And Not WasChar;
- AskTerminator:=Ch;
- AskString:=Copy(AS,1,Cursor);
- End; { AskString }
-
- Function AskInt(Prompt: String255; Param: Integer; MaxLen: Byte): Integer;
- Var
- Temp: String255;
- P,I: Integer;
- Begin
- Str(Param,Temp);
- Temp:=AskString(Prompt,Temp, ['0'..'9', '-'], MaxLen);
- Val(Temp,P,I);
- If Length(Temp)=0 Then AskInt:=0
- Else If I=0 Then AskInt:=P
- Else AskInt:=Param;
- End; { AskInt }
-
- Function AskReal(Prompt: String255; Param: Real; MaxLen: Byte): Real;
- Var
- Temp: String255;
- P: Real;
- I: Integer;
- Begin
- Str(Param:1:12,Temp);
- I:=14;
- While Temp[I]='0' Do I:=Pred(I);
- If Temp[I]='.' Then I:=Pred(I);
- Temp:=AskString(Prompt,Copy(Temp,1,I),['0'..'9', '.', '-'], MaxLen);
- Val(Temp,P,I);
- If Length(Temp)=0 Then AskReal:=0.0
- Else If I=0 Then AskReal:=P
- Else AskReal:=Param;
- End; { AskReal }
-
- (* A program to test the routines... close this comment to enable it. For
- best results, turn control-C checking off by putting {$C-} at the top of
- the source code.
-
- Var
- X: String[40];
- Y: Integer;
- Z: Real;
-
- Begin
- ShowBuffer:=True;
- X:='This is a test.';
- Repeat
- X:=AskString('Edit the buffer: ',X,[#0..#255],40);
- WriteLn;
- WriteLn(X);
- Until X='';
- Y:=100;
- ShowBuffer:=False;
- Repeat
- Y:=AskInt('Edit the integer: ',Y,10);
- WriteLn;
- WriteLn(Y);
- Until Y=0;
- Z:=Pi;
- ShowBuffer:=True;
- Repeat
- Z:=AskReal('Edit the real: ',Z,24);
- WriteLn;
- WriteLn(Z:1:11);
- Until Z=0.0;
- End.
- (**)